<?php

/**
 * Hooks of Form Helper helps create full admin page view.
 *
 * PHP versions 5
 * CAKEPHP versions 2.x
 * 
 * Green CMS - Content Management System and Framework Powerfull by Cakephp
 * Copyright 2012, GREEN GLOBAL CO., LTD (toancauxanh.vn)
 * 
 * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
 * Copyright 2005-2011, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @author        Technology Lab No.I <tech1@toancauxanh.vn>
 * @link          
 * @package       Green.Helper
 * @since         Green v 1.0
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */
App::uses('FormHelper', 'View/Helper');
App::uses('CakeEvent', 'Event');

class HookFormHelper extends FormHelper {

    /**
     * The model used for the current form.
     *
     * @var string
     */
    protected $_currentModel = null;

    /**
     * Guess the location for a model based on its name and tries to create a new instance
     * or get an already created instance of the model
     *
     * @param mixed $model string model name or get current model
     * @return Model model instance
     */
    public function getModel($model = null) {
        if (empty($model) && $this->_currentModel) {
            $model = $this->_currentModel;
        }
        return parent::_getModel($model);
    }

    /**
     * Skip form secure
     *
     * @param boolean $create
     * @return void
     */
    protected function _skipSecure($create = false) {
        if (isset($this->request->params['_backupToken'])) {
            $this->request->params['_Token'] = $this->request->params['_backupToken'];
            unset($this->request->params['_backupToken']);
        }
        if ($create && isset($this->request->params['_Token'])) {
            $this->request->params['_backupToken'] = $this->request->params['_Token'];
            unset($this->request->params['_Token']);
        }
    }

    /**
     * Returns false if given form field described by the current entity has no errors.
     * Otherwise it returns the validation message
     *
     * @return mixed Either false when there or no errors, or an array of error
     *    strings. An error string could be ''.
     * 
     * @see FormHelper::tagIsInvalid
     */
    public function tagIsInvalid() {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.tagIsInvalid', $this));
        return parent::tagIsInvalid();
    }

    /**
     * Returns an HTML FORM element.
     * 
     * @param string $model The model object which the form is being defined for.  Should
     *   include the plugin name for plugin forms.  e.g. `ContactManager.Contact`.
     * @param array $options An array of html attributes and options.
     * @return string An formatted opening FORM tag.
     * 
     * @see FormHelper::create
     */
    public function create($model = null, $options = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.create', $this, array(&$model, &$options)));
        if (isset($options['secure']) && $options['secure'] === false && isset($this->request->params['_Token'])) {
            $this->_skipSecure(true);
        }
        $output = parent::create(&$model, $options);
        if ($model !== false) {
            $this->_currentModel = $model;
        }
        return $output;
    }

    /**
     * Closes an HTML form, cleans up values set by FormHelper::create(), and writes hidden
     * input fields where appropriate.
     * 
     * @param mixed $options as a string will use $options as the value of button,
     * @return string a closing FORM tag optional submit button.
     * 
     * @see FormHelper::end
     */
    public function end($options = null) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.end', $this, array(&$options)));
        $this->_currentModel = null;
        $output = parent::end($options);
        $this->_skipSecure(false);
        return $output;
    }

    /**
     * Generates a hidden field with a security hash based on the fields used in the form.
     *
     * @param array $fields The list of fields to use when generating the hash
     * @return string A hidden input field with a security hash
     * 
     * @see FormHelper::secure
     */
    public function secure($fields = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.secure', $this, array(&$fields)));
        return parent::secure($fields);
    }

    /**
     * Add to or get the list of fields that are currently unlocked.
     * Unlocked fields are not included in the field hash used by SecurityComponent
     * unlocking a field once its been added to the list of secured fields will remove
     * it from the list of fields.
     *
     * @param string $name The dot separated name for the field.
     * @return mixed Either null, or the list of fields.
     * 
     * @see FormHelper::unlockField
     */
    public function unlockField($name = null) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.unlockField', $this, array(&$name)));
        return parent::unlockField($name);
    }

    /**
     * Returns a formatted error message for given FORM field, NULL if no errors.
     *
     * @param string $field A field name, like "Modelname.fieldname"
     * @param mixed $text Error message as string or array of messages.
     * If array contains `attributes` key it will be used as options for error container
     * @param array $options Rendering options for <div /> wrapper tag
     * @return string If there are errors this method returns an error message, otherwise null.
     * 
     * @see FormHelper::error
     */
    public function error($field, $text = null, $options = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.error', $this, array(&$field, &$text, &$options)));
        return parent::error($field, $text, $options);
    }

    /**
     * Returns a formatted LABEL element for HTML FORMs. Will automatically generate
     * a for attribute if one is not provided.
     *
     * @param string $fieldName This should be "Modelname.fieldname"
     * @param string $text Text that will appear in the label field.  If
     *   $text is left undefined the text will be inflected from the
     *   fieldName.
     * @param mixed $options An array of HTML attributes, or a string, to be used as a class name.
     * @return string The formatted LABEL element
     * 
     * @see FormHelper::label
     */
    public function label($fieldName = null, $text = null, $options = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.label', $this, array(&$fieldName, &$text, &$options)));
        return parent::label($fieldName, $text, $options);
    }

    /**
     * Generate a set of inputs for `$fields`.  If $fields is null the current model
     * will be used.
     *
     * @param mixed $fields An array of fields to generate inputs for, or null.
     * @param array $blacklist a simple array of fields to not create inputs for.
     * @return string Completed form inputs.
     * 
     * @see FormHelper::inputs
     */
    public function inputs($fields = null, $blacklist = null) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.inputs', $this, array(&$fields, &$blacklist)));
        return parent::inputs($fields, $blacklist);
    }

    /**
     * Generates a form input element complete with label and wrapper div
     *
     * @param string $fieldName This should be "Modelname.fieldname"
     * @param array $options Each type of input takes different options.
     * @return string Completed form widget.
     * 
     * @see FormHelper::input
     */
    public function input($fieldName, $options = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.input', $this, array(&$fieldName, &$options)));
        return parent::input($fieldName, $options);
    }

    /**
     * Creates a checkbox input widget.
     *
     * @param string $fieldName Name of a field, like this "Modelname.fieldname"
     * @param array $options Array of HTML attributes.
     * @return string An HTML text input element.
     * 
     * @see FormHelper::checkbox
     */
    public function checkbox($fieldName, $options = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.checkbox', $this, array(&$fieldName, &$options)));
        return parent::checkbox($fieldName, $options);
    }

    /**
     * Creates a set of radio widgets. Will create a legend and fieldset
     * by default.  Use $options to control this
     *
     * @param string $fieldName Name of a field, like this "Modelname.fieldname"
     * @param array $options Radio button options array.
     * @param array $attributes Array of HTML attributes, and special attributes above.
     * @return string Completed radio widget set.
     * 
     * @see FormHelper::radio
     */
    public function radio($fieldName, $options = array(), $attributes = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.radio', $this, array(&$fieldName, &$options, &$attributes)));
        return parent::radio($fieldName, $options, $attributes);
    }

    /**
     * Creates a textarea widget.
     *
     * @param string $fieldName Name of a field, in the form "Modelname.fieldname"
     * @param array $options Array of HTML attributes, and special options above.
     * @return string A generated HTML text input element
     * 
     * @see FormHelper::textarea
     */
    public function textarea($fieldName, $options = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.textarea', $this, array(&$fieldName, &$options)));
        return parent::textarea($fieldName, $options);
    }

    /**
     * Creates a hidden input field.
     *
     * @param string $fieldName Name of a field, in the form of "Modelname.fieldname"
     * @param array $options Array of HTML attributes.
     * @return string A generated hidden input
     * 
     * @see FormHelper::hidden
     */
    public function hidden($fieldName, $options = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.hidden', $this, array(&$fieldName, &$options)));
        return parent::hidden($fieldName, $options);
    }

    /**
     * Creates file input widget.
     *
     * @param string $fieldName Name of a field, in the form "Modelname.fieldname"
     * @param array $options Array of HTML attributes.
     * @return string A generated file input.
     * 
     * @see FormHelper::file
     */
    public function file($fieldName, $options = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.file', $this, array(&$fieldName, &$options)));
        return parent::file($fieldName, $options);
    }

    /**
     * Creates a button element.
     *
     *  @param string $title The button's caption. Not automatically HTML encoded
     * @param array $options Array of options and HTML attributes.
     * @return string A HTML button tag.
     * 
     * @see FormHelper::button
     */
    public function button($title, $options = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.button', $this, array(&$title, &$options)));
        return parent::button($title, $options);
    }

    /**
     * Create a `<button>` tag with a surrounding `<form>` that submits via POST.
     *
     * @param string $title The button's caption. Not automatically HTML encoded
     * @param mixed $url URL as string or array
     * @param array $options Array of options and HTML attributes.
     * @return string A HTML button tag.
     * 
     * @see FormHelper::postButton
     */
    public function postButton($title, $url, $options = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.postButton', $this, array(&$title, &$url, &$options)));
        return parent::postButton($title, $url, $options);
    }

    /**
     * Creates an HTML link, but access the url using method POST.
     * Requires javascript to be enabled in browser.
     *
     * @param string $title The content to be wrapped by <a> tags.
     * @param mixed $url Cake-relative URL or array of URL parameters, or external URL (starts with http://)
     * @param array $options Array of HTML attributes.
     * @param string $confirmMessage JavaScript confirmation message.
     * @return string An `<a />` element.
     * 
     * @see FormHelper::postLink
     */
    public function postLink($title, $url = null, $options = array(), $confirmMessage = false) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.postLink', $this, array(&$title, &$url, &$options, &$confirmMessage)));
        return parent::postLink($title, $url, $options, $confirmMessage);
    }

    /**
     * Creates a submit button element.  This method will generate `<input />` elements that
     * can be used to submit, and reset forms by using $options.  image submits can be created by supplying an
     * image path for $caption.
     *
     * @param string $caption The label appearing on the button OR if string contains :// or the
     *  extension .jpg, .jpe, .jpeg, .gif, .png use an image if the extension
     *  exists, AND the first character is /, image is relative to webroot,
     *  OR if the first character is not /, image is relative to webroot/img.
     * @param array $options Array of options.  See above.
     * @return string A HTML submit button
     * 
     * @see FormHelper::submit
     */
    public function submit($caption = null, $options = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.submit', $this, array(&$caption, &$options)));
        return parent::submit($caption, $options);
    }

    /**
     * Returns a formatted SELECT element.
     *
     * @param string $fieldName Name attribute of the SELECT
     * @param array $options Array of the OPTION elements (as 'value'=>'Text' pairs) to be used in the
     * 	SELECT element
     * @param array $attributes The HTML attributes of the select element.
     * @return string Formatted SELECT element
     * 
     * @see FormHelper::select
     */
    public function select($fieldName, $options = array(), $attributes = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.select', $this, array(&$fieldName, &$options, &$attributes)));
        return parent::select($fieldName, $options, $attributes);
    }

    /**
     * Returns a SELECT element for days.
     *
     * @param string $fieldName Prefix name for the SELECT element
     * @param array $attributes HTML attributes for the select element
     * @return string A generated day select box.
     * 
     * @see FormHelper::day
     */
    public function day($fieldName = null, $attributes = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.day', $this, array(&$fieldName, &$attributes)));
        return parent::day($fieldName, $attributes);
    }

    /**
     * Returns a SELECT element for years
     *
     * @param string $fieldName Prefix name for the SELECT element
     * @param integer $minYear First year in sequence
     * @param integer $maxYear Last year in sequence
     * @param array $attributes Attribute array for the select elements.
     * @return string Completed year select input
     * 
     *  @see FormHelper::year
     */
    public function year($fieldName, $minYear = null, $maxYear = null, $attributes = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.year', $this, array(&$fieldName, &$minYear, &$maxYear, &$attributes)));
        return parent::year($fieldName, $minYear, $maxYear, $attributes);
    }

    /**
     * Returns a SELECT element for months.
     *
     * @param string $fieldName Prefix name for the SELECT element
     * @param array $attributes Attributes for the select element
     * @return string A generated month select dropdown.
     * 
     *  @see FormHelper::month
     */
    public function month($fieldName, $attributes = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.month', $this, array(&$fieldName, &$attributes)));
        return parent::month($fieldName, $attributes);
    }

    /**
     * Returns a SELECT element for hours.
     *
     * @param string $fieldName Prefix name for the SELECT element
     * @param boolean $format24Hours True for 24 hours format
     * @param array $attributes List of HTML attributes
     * @return string Completed hour select input
     * 
     *  @see FormHelper::hour
     */
    public function hour($fieldName, $format24Hours = false, $attributes = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.hour', $this, array(&$fieldName, &$format24Hours, &$attributes)));
        return parent::hour($fieldName, $format24Hours, $attributes);
    }

    /**
     * Returns a SELECT element for minutes.
     *
     * @param string $fieldName Prefix name for the SELECT element
     * @param string $attributes Array of Attributes
     * @return string Completed minute select input.
     * 
     * @see FormHelper::minute
     */
    public function minute($fieldName, $attributes = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.minute', $this, array(&$fieldName, &$attributes)));
        return parent::minute($fieldName, $attributes);
    }

    /**
     * Returns a SELECT element for AM or PM.
     *
     * @param string $fieldName Prefix name for the SELECT element
     * @param string $attributes Array of Attributes
     * @return string Completed meridian select input
     *
     * @see FormHelper::meridian
     */
    public function meridian($fieldName, $attributes = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.meridian', $this, array(&$fieldName, &$attributes)));
        return parent::meridian($fieldName, $attributes);
    }

    /**
     * Returns a set of SELECT elements for a full datetime setup: day, month and year, and then time.
     *
     * @param string $fieldName Prefix name for the SELECT element
     * @param string $dateFormat DMY, MDY, YMD, or null to not generate date inputs.
     * @param string $timeFormat 12, 24, or null to not generate time inputs.
     * @param string $attributes array of Attributes
     * @return string Generated set of select boxes for the date and time formats chosen.
     * 
     * @see FormHelper::dateTime
     */
    public function dateTime($fieldName, $dateFormat = 'DMY', $timeFormat = '12', $attributes = array()) {
        $this->getEventManager()->dispatch(new CakeEvent('Helper.Form.dateTime', $this, array(&$fieldName, &$dateFormat, &$timeFormat, &$attributes)));
        return parent::dateTime($fieldName, $dateFormat, $timeFormat, $attributes);
    }

}